package com.ohxwj.modules.web.controller;

import com.ohxwj.common.annotation.SysLog;
import com.ohxwj.common.utils.PageUtils;
import com.ohxwj.common.utils.R;
import com.ohxwj.modules.sys.entity.SysUserEntity;
import com.ohxwj.modules.sys.entity.SysUserTokenEntity;
import com.ohxwj.modules.sys.service.ShiroService;
import com.ohxwj.modules.web.entity.WebArticleEntity;
import com.ohxwj.modules.web.entity.WebContextVo;
import com.ohxwj.modules.web.entity.WebLabelEntity;
import com.ohxwj.modules.web.entity.WebMenuEntity;
import com.ohxwj.modules.web.service.WebArticleService;
import com.ohxwj.modules.web.service.WebLabelService;
import com.ohxwj.modules.web.service.WebMenuService;
import org.apache.http.HttpStatus;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Created by Administrator on 2018-04-16.
 */
@RestController
@RequestMapping("/web/article")
public class WebArticleController extends AbstractAction {


    @Autowired
    private WebArticleService webArticleService;
    @Autowired
    private WebMenuService webMenuService;
    @Autowired
    private ShiroService shiroService;

    private SysUserEntity getUser() {
        return (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
    }

    @RequestMapping("/info")
    public R info(HttpServletRequest request) {
        int articleId = getIntegerParamFromRequest(request, "id");
        int hit = getIntegerParamFromRequest(request, "hit");
        int menuId = getIntegerParamFromRequest(request, "menuId");
        WebArticleEntity webArticleEntity = webArticleService.loadArticleById(articleId);
        if (null == webArticleEntity) {
            return R.error(HttpStatus.SC_NOT_FOUND, "文章不存在");
        } else {
            int prevId = 0;
            int nextId = 0;
            int currentIndex = 0;
            String prevTitle = null;
            String nextTitle = null;
            if (menuId > 0) {
                Map<String, Object> params = new HashMap<>();
                params.put("limit", 1000);
                params.put("offset", 0);
                params.put("page", 1);
                params.put("menuId", menuId);
                params.put("status", WebArticleEntity.STATUS_APPROVE);
                List<WebArticleEntity> webArticleEntities = webArticleService.queryArticles(params);
                for (int i = 0; i < webArticleEntities.size(); i ++) {
                    if (webArticleEntities.get(i).getId() == webArticleEntity.getId()) {
                        currentIndex = i;
                    }
                }
                if (currentIndex - 1 >= 0 && null != webArticleEntities.get(currentIndex - 1)) {
                    prevId = webArticleEntities.get(currentIndex - 1).getId();
                    prevTitle = webArticleEntities.get(currentIndex - 1).getTitle();
                }
                if (currentIndex + 1 < webArticleEntities.size() && null != webArticleEntities.get(currentIndex + 1)) {
                    nextId = webArticleEntities.get(currentIndex + 1).getId();
                    nextTitle = webArticleEntities.get(currentIndex + 1).getTitle();
                }
            }
            if (hit > 0) {
                webArticleService.updateWebArticleHit(webArticleEntity.getId());
            }
            R r = R.ok().put("context", new WebContextVo(prevId, prevTitle, nextId, nextTitle));
            return r.put("data", webArticleEntity);
        }

    }

    @RequestMapping("/teacherPage")
    public R teacherPage(HttpServletRequest request) {
        int menuId = getIntegerParamFromRequest(request, "menuId");
        int page = getIntegerParamFromRequest(request, "page");
        int pageSize = getIntegerParamFromRequest(request, "pageSize");
        int status = getIntegerParamFromRequest(request, "status");
        String title = getStringParamFromRequest(request, "title");
        String creatorName = getStringParamFromRequest(request, "creatorName");
        Date begin = getDateParamFromRequest(request, "begin");
        Date end = getDateParamFromRequest(request, "end");
        Map<String, Object> params = new HashMap<>();
        params.put("page", page);
        params.put("menuId", menuId);
        params.put("status", status);
        params.put("limit", pageSize);
        params.put("offset", (page - 1) * pageSize);
        params.put("title", title);
        params.put("creatorName", creatorName);
        params.put("begin", begin);
        params.put("end", end);
        SysUserTokenEntity sysUserTokenEntity = shiroService.queryByToken(getStringParamFromRequest(request,"token"));
        if (sysUserTokenEntity != null) {
            params.put("userId", sysUserTokenEntity.getUserId());
        }
        List<WebArticleEntity> webArticleEntities = webArticleService.queryTeachers(params);
        int total = webArticleService.queryTeacherCount(params);
        PageUtils pageUtils = new PageUtils(webArticleEntities, total, pageSize, page);
        return R.ok().put("data", pageUtils);
    }

    @RequestMapping("/list")
    public R list(HttpServletRequest request) {
        int page = getIntegerParamFromRequest(request, "page");
        int pageSize = getIntegerParamFromRequest(request, "pageSize");
        int menuId = getIntegerParamFromRequest(request, "menuId");
        int status = getIntegerParamFromRequest(request, "status");
        String title = getStringParamFromRequest(request, "title");
        String creatorName = getStringParamFromRequest(request, "creatorName");
        Date begin = getDateParamFromRequest(request, "begin");
        Date end = getDateParamFromRequest(request, "end");
        int type = getIntegerParamFromRequest(request, "type");

        Map<String, Object> params = new HashMap<>();
        params.put("page", page);
        params.put("menuId", menuId);
        params.put("status", status);
        params.put("limit", pageSize);
        params.put("offset", (page - 1) * pageSize);
        params.put("title", title);
        params.put("creatorName", creatorName);
        params.put("begin", begin);
        params.put("end", end);
        params.put("type", type);
        SysUserTokenEntity sysUserTokenEntity = shiroService.queryByToken(getStringParamFromRequest(request,"token"));
        if (sysUserTokenEntity != null) {
            params.put("userId", sysUserTokenEntity.getUserId());
        }
        List<WebArticleEntity> webArticleEntities = webArticleService.queryArticles(params);
        int total = webArticleService.queryTotal(params);
        PageUtils pageUtils = new PageUtils(webArticleEntities, total, pageSize, page);
        return R.ok().put("data", pageUtils);
    }

    @RequestMapping("/add")
    @RequiresPermissions("web:article:save")
    public R add(@RequestBody WebArticleEntity webArticleEntity) {
        int menuId = webArticleEntity.getMenuId();
        int type = webArticleEntity.getType();
        WebMenuEntity webMenuEntity = webMenuService.loadWebMenuById(menuId);
        if (null == webMenuEntity || webMenuEntity.getType() != type) {
            return R.error("栏目和文章类型不符合");
        }
        SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
        webArticleEntity.setUserId(sysUserEntity.getUserId());
        try {
            webArticleService.insertWebArticle(webArticleEntity);
        } catch (Exception e) {
            return R.error("该栏目已存在标题相同标题文章");
        }
        return R.ok();
    }

    @RequestMapping("/update")
    @RequiresPermissions("web:article:update")
    public R update(@RequestBody WebArticleEntity webArticleEntity) {
        WebArticleEntity oldArticle = webArticleService.loadArticleById(webArticleEntity.getId());
        if (null == oldArticle) {
            return R.error(HttpStatus.SC_NOT_FOUND, "文章不存在");
        }
        SysUserEntity sysUserEntity = getUser();
        Set<String> permsSet = shiroService.getUserPermissions(sysUserEntity.getUserId());
        if (sysUserEntity.getUserId().equals(oldArticle.getUserId())) {
            if (!permsSet.contains("web:article:audit")) {
                return R.error("没有审核权限不能修改他人文章");
            }
        }
        int menuId = webArticleEntity.getMenuId();
        int type = webArticleEntity.getType();
        WebMenuEntity webMenuEntity = webMenuService.loadWebMenuById(menuId);
        if (null == webMenuEntity || webMenuEntity.getType() != type) {
            return R.error("栏目和文章类型不符合");
        }

        try {
            webArticleService.updateWebArticle(webArticleEntity);
            webArticleService.updateArticleLabel(webArticleEntity.getId(), webArticleEntity.getLabelId());
        } catch (Exception e) {
            return R.error("该栏目已存在标题相同标题文章");
        }
        webArticleService.updateWebArticleStatus(webArticleEntity.getId(), webArticleEntity.getStatus());

        return R.ok();
    }

    @SysLog("delete article")
    @RequestMapping("/delete")
//    @RequiresPermissions("web:article:delete")
    public R deleteArticle(int id) {
        WebArticleEntity oldArticle = webArticleService.loadArticleById(id);
        if (null == oldArticle) {
            return R.error(HttpStatus.SC_NOT_FOUND, "文章不存在");
        }
        SysUserEntity sysUserEntity = getUser();
        Set<String> permsSet = shiroService.getUserPermissions(sysUserEntity.getUserId());
        if (sysUserEntity.getUserId().equals(oldArticle.getUserId())) {
            if (!permsSet.contains("web:article:audit")) {
                return R.error("没有审核权限不能删除他人文章");
            }
        }
        webArticleService.deleteWebArticle(id);

        return R.ok();
    }

    @SysLog("audit article")
    @RequestMapping("/audit")
    @RequiresPermissions("web:article:audit")
    public R audit(int id, int status) {
        WebArticleEntity oldArticle = webArticleService.loadArticleById(id);
        if (null == oldArticle) {
            return R.error(HttpStatus.SC_NOT_FOUND, "文章不存在");
        }
        if (oldArticle.getStatus() != WebArticleEntity.STATUS_SUBMIT) {
            return R.error("只有待审核文章才可进行审核");
        }
        webArticleService.updateWebArticleStatus(id, status);

        return R.ok();
    }

    @RequestMapping("/paste")
    public R paste(int articleId, int menuId) {
        WebArticleEntity webArticleEntity = webArticleService.loadArticleById(articleId);
        if (null == webArticleEntity) {
            return R.error("文章不存在");
        }
        WebMenuEntity webMenuEntity = webMenuService.loadWebMenuById(menuId);
        if (null == webMenuEntity) {
            return R.error("栏目不存在");
        }
        if (webArticleEntity.getType() != webMenuEntity.getType()) {
            return R.error("文章栏目不匹配");
        }
        webArticleEntity.setMenuId(menuId);
        SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
        webArticleEntity.setUserId(sysUserEntity.getUserId());
        try {
            webArticleService.insertWebMenuArticle(menuId, articleId, webArticleEntity.getLabelId());
        } catch (Exception e) {
            return R.error("该栏目已存在标题相同标题文章");
        }
        return R.ok();
    }

    //标签管理
    @Autowired
    private WebLabelService webLabelService;

    @RequestMapping("/addLabel")
    public R addLabel(int menuId, String labelName) {
        WebMenuEntity webMenuEntity = webMenuService.loadWebMenuById(menuId);
        if (null == webMenuEntity || webMenuEntity.getType() != WebMenuEntity.LABEL_TYPE) {
            return R.error("栏目和文章类型不符合");
        }
        List<WebLabelEntity> webLabelEntities = webLabelService.queryLabels(menuId);
        double priority = 0.0;
        if (null != webLabelEntities && webLabelEntities.size() > 0) {
            priority = webLabelEntities.get(webLabelEntities.size() - 1).getPriority() + 1;
        }
        try {
            webLabelService.addLabel(menuId, labelName, priority);
        } catch (Exception e) {
            return R.error("该栏目已存在相同标签");
        }
        return R.ok();
    }

    @RequestMapping("/queryLabels")
    public R queryLabels(int menuId) {
        List<WebLabelEntity> webLabelEntities = webLabelService.queryLabels(menuId);
        return R.ok().put("data", webLabelEntities);
    }

    @RequestMapping("/deleteLabels")
    public R deleteLabels(int labelId) {
        List<WebArticleEntity> webArticleEntities = webArticleService.queryArticleByLabelId(labelId);
        if (null != webArticleEntities && webArticleEntities.size() > 0) {
            return R.error(HttpStatus.SC_FORBIDDEN, "该标签下有文章，不可删除");
        }
        webLabelService.deleteLabel(labelId);

        return R.ok();
    }

    @RequestMapping("/updateLabel")
    public R updateLabel(int labelId, String labelName) {
        try {
            webLabelService.updateLabel(labelId, labelName);
        } catch (Exception e) {
            return R.error("该栏目已存在相同标签");
        }
        return R.ok();
    }

    private double getMiddlePriority(double i, double j) {
        return (i + j) / 2;
    }


    // 上移
    @RequestMapping(value = "/updateLabelPriority")
    public R updateLabelPriority(int menuId, int labelId) {
        List<WebLabelEntity> webLabelEntities = webLabelService.queryLabels(menuId);
        int i = -1;
        for (int j = 0; j < webLabelEntities.size(); j ++) {
            if (webLabelEntities.get(j).getId() == labelId) {
                i = j;
            }
        }
        if (i < 0) {
            return R.error(HttpStatus.SC_NOT_FOUND, "无标签");
        }
        if (i <= 1) {
            webLabelService.updateLabelPriority(labelId, webLabelEntities.get(0).getPriority() - 1);
        } else {
            webLabelService.updateLabelPriority(labelId, getMiddlePriority(webLabelEntities.get(i - 1).getPriority(), webLabelEntities.get(i - 2).getPriority()));
        }
        return R.ok();
    }
}
